﻿#include "usk/core/usk_core.h"
#include "Poco/ThreadPool.h"
#include "cppmicroservices/AnyMap.h"
#include "cppmicroservices/BundleContext.h"
#include "cppmicroservices/FrameworkEvent.h"
#include "cppmicroservices/em/EventHandler.hpp"
#include "event/usk_event_admin_impl.h"
#include "fmt/format.h"
#include "logger/usk_logger_impl_private.hpp"
#include "logger/usk_logservice_impl.h"
#include "osgi_private.hpp"


#include <chrono>


using namespace cppmicroservices::logservice;

namespace usk {
    namespace core {
        OSGI::OSGI() {
            d_ = std::make_shared<OsgiPrivate>();
            USKLoggerImplPrivate::SetLogConfiguration(USKLoggerImplPrivate::GetDefaultLoggerConfiguration());
            d_->log_service_ = std::make_shared<USKLogserviceImpl>("OSGI");
            d_->event_admin_ = std::make_shared<USKEventAdminImpl>(this);
        }

        void OSGI::OnEvent(const void *pSender, cppmicroservices::service::em::Event &ev) {
            LOG_DEBUG("on event:{}", ev.GetTopic().c_str());
            const EventTaskers *tasker = static_cast<EventTaskers *>(const_cast<void *>(pSender));
            if (nullptr == tasker) {
                return;
            }
            auto bundle_context = GetBundleContext();
            for (auto s: tasker->event_handlers) {
                auto handler = bundle_context.GetService<EventHandler>(s);
                if (nullptr == handler) {
                    continue;
                }
                handler->HandleEvent(ev);
            }
            delete tasker;
        }

        OSGI &OSGI::GetInstance() {
            static OSGI instance;
            return instance;
        }


        bool OSGI::Init() {
            try {
                LOG_INFO("Init OSGI Framework");
                // 初始化CppMicroServices框架
                d_->frame_work_->Init();

                // 启动CppMicroServices,会启动框架内置的system bundle
                LOG_INFO("Start OSGI Framework");
                d_->frame_work_->Start();

                // 注册LogService服务到osgi
                d_->log_service_registration_ =
                        GetBundleContext().RegisterService<LogService>(
                                std::move(d_->log_service_));
                if (d_->log_service_registration_) {
                    LOG_INFO("Succeed Register LogService Service");
                } else {
                    LOG_ERROR("Fail to Register LogService Service");
                }

                // 注册EventAdmin服务到osgi
                d_->event_admin_registration_ =
                        GetBundleContext().RegisterService<EventAdmin>(
                                std::move(d_->event_admin_));
                if (d_->event_admin_registration_) {
                    LOG_INFO("Succeed Register EventAdmin Service");
                } else {
                    LOG_ERROR("Fail to Register EventAdmin Service");
                }

                // d_->topic_ldap_filter_->CreateTopicFilter("org/huawei");
                // auto filter = d_->topic_ldap_filter_->CreateTopicFilter("org/huawei");
                //
                // cppmicroservices::AnyMap props;
                // props["Language"] = std::string("English");
                //
                // cppmicroservices::AnyMap p1;
                // p1["event.topics"] = std::string("org/huawei");
                //
                // cppmicroservices::AnyMap p2;
                // p2["event.topics"] = std::string("org/huawei1");
                //
                // cppmicroservices::AnyMap p3;
                // p3["event.topics"] = std::string("org/huawei/sub");
                //
                // cppmicroservices::AnyMap p4;
                // p4["event.topics"] = std::string("org/sub");
                //
                //
                // LOG_DEBUG("P1 Match:{}", filter->Match(p1));
                // LOG_DEBUG("P2 Match:{}", filter->Match(p2));
                // LOG_DEBUG("P3 Match:{}", filter->Match(p3));
                // LOG_DEBUG("P4 Match:{}", filter->Match(p4));

            } catch (...) {
                LOG_ERROR("Failed to initialize OSGI Framework");
                return false;
            }

            return true;
        }

        void OSGI::UnInit() {
            // 注销EventAdmin服务对象
            if (d_->event_admin_registration_) {
                LOG_INFO("Unregister EventAdmin Service");
                d_->event_admin_registration_.Unregister();
            }

            // 注销LogService服务对象
            if (d_->log_service_registration_) {
                LOG_INFO("Unregister LogService Service");
                d_->log_service_registration_.Unregister();
            }

            LOG_INFO("Stop OSGI Framework");
            d_->frame_work_->Stop();
            d_->frame_work_->WaitForStop(std::chrono::seconds(2));

            d_->event_admin_.reset();
            d_->log_service_.reset();

            Poco::ThreadPool::defaultPool().joinAll();
        }

        BundleContext OSGI::GetBundleContext() { return d_->frame_work_->GetBundleContext(); }

        std::shared_ptr<LogService> OSGI::GetLogService() { return d_->log_service_; }

        bool OSGI::AddBundleInstallPath(const char *path) { return d_->AddBundleInstallPath(path); }

        void OSGI::InstallBundles() {
            std::vector<std::string> failed_bundle_path;
            for (auto location: d_->install_bundle_files_) {
                auto result = d_->frame_work_->GetBundleContext().InstallBundles(location);
                if (result.empty()) {
                    failed_bundle_path.push_back(location);
                }
            }
            for (auto location: failed_bundle_path) {
                d_->install_bundle_files_.erase(location);
            }
        }

        void OSGI::PostEvent(Event const &evt) {
            if (nullptr == d_->event_admin_) {
                return;
            }
            d_->event_admin_->PostEvent(evt);
        }

        void OSGI::SendEvent(Event const &evt) {
            if (nullptr == d_->event_admin_) {
                return;
            }
            d_->event_admin_->SendEvent(evt);
        }

        std::vector<Bundle> OSGI::GetBundles() { return d_->frame_work_->GetBundleContext().GetBundles(); }
    } // namespace core
} // namespace usk
